package com.mingserve.common.core.utils;

import com.mingserve.common.core.text.Convert;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.ParseException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 时间工具类
 *
 * @author lvwshuai
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    /**
     * 仅显示年月日，例如 2021-10-24
     */
    public static String YYYY_MM_DD = "yyyy-MM-dd";
    /**
     * 仅显示月日，例如 10月24日
     */
    public static String MM_DD = "MM月dd日";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    /**
     * 显示年月日时分秒，例如 2021-10-24 09:51:33
     */
    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 仅显示时分秒，例如 09:51:33
     */
    public static final String HH_MM_SS = "HH:mm:ss";

    /**
     * 每周的天数.
     */
    public static final long DAYS_PER_WEEK = 7L;

    /**
     * 每毫秒的微秒数 1000
     */
    public static final long MICROS_PER_MILLI = 1000;
    /**
     * 每秒的毫秒数 1000
     */
    public static final long MILLIS_PER_SECOND = 1000;
    /**
     * 每分钟的毫秒数 60_000
     */
    public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
    /**
     * 每小时毫秒数 3600_000
     */
    public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
    /**
     * 每天的毫秒数 86400_000
     */
    public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;

    /**
     * 时间戳 秒长度.
     */
    public static final int TIMESTAMP_SECOND_LENGTH = 10;
    /**
     * 时间戳 毫秒长度.
     */
    public static final int TIMESTAMP_MILLISECOND_LENGTH = 13;
    /**
     * 时间戳 微秒长度.
     */
    public static final int TIMESTAMP_MICROSECOND_LENGTH = 16;

    private static final String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd HH:mm:ss
     *
     * @return String 日期和时间字符串，例如 2021-10-24 09:51:33
     */
    public static String getDateTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 得到当前时间字符串. 默认格式为 HH:mm:ss
     *
     * @return String 时间字符串，例如 09:51:33
     */
    public static String getTime()
    {
        return dateTimeNow(HH_MM_SS);
    }

    /**
     * 得到当前时间字符串. 默认格式为 yyyyMMddHHmmss
     *
     * @return String 时间字符串，例如 20211024095133
     */
    public static String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    /**
     * 格式化当前时间字符串
     *
     * @return String 时间字符串
     */
    public static String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static String parseDateToStr(final String format, final Date date)
    {
        return DateFormatUtils.format(date, format);
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static String datePath() {return DateFormatUtils.format(new Date(), "yyyy/MM/dd");}

    /**
     * 日期路径 即年/月/日 如2018/08/08
     *
     * @param timestamp 时间戳
     */
    public static String datePath(Long timestamp)
    {
        return formatDate(timestamp, "yyyy/MM/dd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str)
    {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算两个时间差
     *
     * @param endTime   最后时间
     * @param startTime 开始时间
     * @return 时间差（天/小时/分钟）
     */
    public static String timeDistance(Date endTime, Date startTime)
    {
        return timeDistance(endTime.getTime(), startTime.getTime());
    }

    /**
     * 计算两个时间差
     *
     * @param endTime   最后时间
     * @param startTime 开始时间
     * @return 时间差（天/小时/分钟）
     */
    public static String timeDistance(Long endTime, Long startTime)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        // long diff = endTime.getTime() - startTime.getTime();
        long diff = endTime - startTime;
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    //====================================日期格式化======================

    /**
     * 获取日期时间字符串，默认格式为（yyyy-MM-dd HH:mm:ss）.
     *
     * @param date    需要转化的日期时间
     * @param pattern 时间格式，例如"yyyy-MM-dd" "HH:mm:ss" "E"等
     * @return String 格式转换后的时间字符串
     */
    public static String formatDate(Date date, Object... pattern)
    {
        String formatDate;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, YYYY_MM_DD_HH_MM_SS);
        }
        return formatDate;
    }

    /**
     * 将LocalDateTime转为自定义的时间格式的字符串
     *
     * @param localDateTime
     * @param format
     * @return
     */
    public static String formatDate(LocalDateTime localDateTime, String format)
    {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return localDateTime.format(formatter);
    }

    /**
     * 时间戳转日期字符串 默认格式为 yyyy-MM-dd HH:mm:ss
     * 默认时区为东8区
     *
     * @param timestamp
     * @return 默认返回 yyyy-MM-dd HH:mm:ss
     */
    public static String formatDate(Long timestamp)
    {
        return formatDate(timestamp, YYYY_MM_DD_HH_MM_SS);
    }

    public static String formatMonthDate(Long timestamp)
    {
        return formatDate(timestamp, MM_DD);
    }

    /**
     * 时间戳转指定格式下的字符串
     * 默认时区为东8区
     *
     * @param timestamp
     * @param format
     * @return
     */
    public static String formatDate(Long timestamp, final String format)
    {
        if (timestamp == null) return null;
        // s(秒)、ms(毫秒)、μs(微秒)、ns(纳秒)
        int length = String.valueOf(timestamp).length();
        Instant instant = null;
        if (length == TIMESTAMP_SECOND_LENGTH) {
            // 秒
            instant = Instant.ofEpochSecond(timestamp);
        } else if (length == TIMESTAMP_MILLISECOND_LENGTH) {
            // 毫秒
            instant = Instant.ofEpochMilli(timestamp);
        } else if (length == TIMESTAMP_MICROSECOND_LENGTH) {
            // 微秒  注意：ofEpochMilli 除1000乘1000会有精度问题，这里要用ofEpochSecond
            instant = Instant.ofEpochSecond(timestamp / 1_000_000L);
        }
        return instant == null ? null : instant.atZone(ZoneOffset.ofHours(8)).toLocalDateTime().format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 时间戳统一转换为微秒
     * 时间戳>当前时间+3小时 也无效
     *
     * @param timestamp 时间戳
     * @return 统一为微秒时间戳
     */
    public static Long formatTimestamp(Object timestamp)
    {
        if (timestamp == null) return null;
        Long ts = Convert.toLong(timestamp);
        // 时间戳统一转成微秒
        int length = String.valueOf(ts).length();
        if (length == TIMESTAMP_SECOND_LENGTH) {
            // 秒 => 微秒
            ts *= 1_000_000L;
        } else if (length == TIMESTAMP_MILLISECOND_LENGTH) {
            // 毫秒 => 微秒
            ts *= 1_000L;
        } else if (length != TIMESTAMP_MICROSECOND_LENGTH) {
            return null;
        }
        // 解析时间戳并检查合法性，并与当前时间进行比较
        Instant instant = Instant.ofEpochSecond(ts / 1_000_000L);
        ZonedDateTime now = ZonedDateTime.now();
        // 如果时间戳在当前时间+3小时之后，则无效
        boolean isValid = ts > 0 && instant.isBefore(now.plusHours(3).toInstant());
        return isValid ? ts : null;
    }

    /**
     * 时间戳统一转换为毫秒
     *
     * @param time 时间戳
     * @return 统一为Java Timestamp 毫秒时间戳
     */
    public static Timestamp formatTimestamp(Long time)
    {
        if (time == null) return null;
        Timestamp timestamp = null;
        // 时间戳统一转成微秒
        int length = String.valueOf(time).length();
        switch (length) {
            case DateUtils.TIMESTAMP_MICROSECOND_LENGTH:
                timestamp = new Timestamp(time / 1000);
                break;
            case DateUtils.TIMESTAMP_MILLISECOND_LENGTH:
                timestamp = new Timestamp(time);
                break;
            case DateUtils.TIMESTAMP_SECOND_LENGTH:
                timestamp = new Timestamp(time * 1000);
                break;
            default:
                break;
        }
        return timestamp;
    }

    /**
     * 获取当前时间时间戳（精确到毫秒级，补000至微秒级）
     *
     * @return
     */
    public static Long getTimestamp()
    {
        // Java中精确到毫秒级 unix中精确到秒级
        return System.currentTimeMillis() * MICROS_PER_MILLI;
    }

    /**
     * 日期转时间戳（精确到毫秒级，补000至微秒级）
     *
     * @param date
     * @return
     */
    public static Long getTimestamp(Date date)
    {
        return date == null ? null : date.getTime() * MICROS_PER_MILLI;
    }

    /**
     * 日期转时间戳（精确到毫秒级，补000至微秒级）
     * 日期格式默认为 yyyy-MM-dd HH:mm:ss 支持微秒级 yyyy-MM-dd HH:mm:ss.SSSSSS
     *
     * @param date
     * @return
     */
    public static Long getTimestamp(String date)
    {
        return getTimestamp(parseDate(date));
    }

    /**
     * LocalDate转时间戳（精确到毫秒级，补000至微秒级）
     *
     * @param localDate
     * @return
     */
    public static Long getTimestamp(LocalDate localDate)
    {
        return localDate == null ? null : LocalDateTime.of(localDate, LocalTime.MIN).toInstant(ZoneOffset.ofHours(8)).toEpochMilli() * MICROS_PER_MILLI;
    }

    /**
     * LocalDateTime转时间戳（精确到毫秒级，补000至微秒级）
     *
     * @param localDateTime
     * @return
     */
    public static Long getTimestamp(LocalDateTime localDateTime)
    {
        return localDateTime == null ? null : localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli() * MICROS_PER_MILLI;
    }

    //====================================日期格式转换======================

    /**
     * 获取当天开始时间（0点）
     * LocalDateTime
     *
     * @return
     */
    public static LocalDateTime getStartTime()
    {
        return LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIN);
    }

    /**
     * 获取某日期当天开始时间（0点）
     * String ==> LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime getStartTime(String date)
    {
        return LocalDateTime.of(toLocalDate(parseDate(date)), LocalTime.MIN);
    }

    /**
     * 获取当天结束时间（24点）
     * LocalDateTime
     *
     * @return
     */
    public static LocalDateTime getEndTime()
    {
        return LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX);
    }

    /**
     * 获取某日期当天结束时间（24点）
     * String ==> LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime getEndTime(String date)
    {
        return LocalDateTime.of(toLocalDate(parseDate(date)), LocalTime.MAX);
    }

    /**
     * String ==> LocalDateTime
     * 将某时间字符串转为自定义时间格式的LocalDateTime
     *
     * @param time
     * @param format
     * @return
     */
    public static LocalDateTime getLocalDateTime(String time, String format)
    {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(time, df);
    }

    /**
     * Date ==> LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Date date)
    {
        if (date == null) return null;
        //An instantaneous point on the time-line.(时间线上的一个瞬时点。)
        Instant instant = date.toInstant();
        // //A time-zone ID, such ZxingCodeUtil {@code Europe/Paris}.(时区)
        // ZoneId zoneId = ZoneId.systemDefault();
        // return instant.atZone(zoneId).toLocalDateTime();
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * Date ==> LocalDate
     */
    public static LocalDate toLocalDate(Date date)
    {
        if (date == null) return null;
        Instant instant = date.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        return localDateTime.toLocalDate();
    }

    /**
     * LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime localDateTime)
    {
        if (localDateTime == null) return null;
        //Combines this date-time with a time-zone to create a  ZonedDateTime.
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * LocalDate ==> Date
     */
    public static Date toDate(LocalDate localDate)
    {
        if (localDate == null) return null;
        LocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 获取当前年份字符串.
     *
     * @return String 当前年份字符串，例如 2015
     */
    public static String getYear()
    {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取当前月份字符串.
     *
     * @return String 当前月份字符串，例如 08
     */
    public static String getMonth()
    {
        return formatDate(new Date(), "MM");
    }

    /**
     * 获取某日期月份字符串.
     *
     * @return String 当前月份字符串，例如 08
     */
    public static String getMonth(Date date)
    {
        return formatDate(date, "MM");
    }

    /**
     * 获取当前天数字符串.
     *
     * @return String 当前天数字符串，例如 11
     */
    public static String getDay()
    {
        return formatDate(new Date(), "dd");
    }

    /**
     * 获取当前星期字符串.
     *
     * @return String 当前星期字符串，例如星期二
     */
    public static String getWeek()
    {
        return formatDate(new Date(), "E");
    }

    /**
     * 得到一个时间延后或前移几天的时间
     *
     * @param strDate：时间     <p>
     *                       支持的日期字符串格式包括 "yyyy-MM-dd","yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm",
     *                       "yyyy/MM/dd","yyyy/MM/dd HH:mm:ss","yyyy/MM/dd HH:mm"
     *                       "yyyy.MM.dd","yyyy.MM.dd HH:mm:ss","yyyy/MM/dd HH:mm"
     * @param delay：前移或后延的天数
     * @return
     */
    public static String addDays(String strDate, int delay)
    {
        try {
            Date d = parseDate(strDate);
            return formatDate(addDays(d, delay), YYYY_MM_DD);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 时间前推或后推分钟,其中minute表示分钟.
     *
     * @param stringTime：时间    <p>
     *                         支持的日期字符串格式包括 "yyyy-MM-dd","yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm",
     *                         "yyyy/MM/dd","yyyy/MM/dd HH:mm:ss","yyyy/MM/dd HH:mm"
     *                         "yyyy.MM.dd","yyyy.MM.dd HH:mm:ss","yyyy/MM/dd HH:mm"
     * @param minute：分钟（有正负之分）
     * @return
     */
    public static String addMinutes(String stringTime, int minute)
    {
        try {
            Date d = parseDate(stringTime);
            return formatDate(addMinutes(d, minute), YYYY_MM_DD_HH_MM_SS);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 时间前推或后推秒钟,其中second表示秒钟.
     *
     * @param timestamp：时间戳
     * @param second：秒钟（有正负之分）
     * @return
     */
    public static String addSeconds(Long timestamp, int second)
    {
        try {
            Date d = parseDate(formatDate(timestamp));
            return formatDate(addSeconds(d, second), YYYYMMDDHHMMSS);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 获取当前日期与指定日期相隔的天数.
     *
     * @param date 给定的日期
     * @return long 日期间隔天数，正数表示给定日期在当前日期之前，负数表示在当前日期之后
     */
    public static long pastDays(Date date)
    {
        if (date == null) return 0;
        return (System.currentTimeMillis() - date.getTime()) / MILLIS_PER_DAY;
    }

    /**
     * 获取当前日期与指定日期相隔的天数.
     *
     * @param timestamp 秒级时间戳
     * @return long 日期间隔天数，正数表示给定日期在当前日期之前，负数表示在当前日期之后
     */
    public static long pastDays(Long timestamp)
    {
        if (timestamp == null) return 0;
        return (System.currentTimeMillis() - timestamp) / MILLIS_PER_DAY;
    }

    /**
     * 获取当前日期与指定日期相隔的小时数.
     *
     * @param timestamp 秒级时间戳
     * @return long 日期间隔天数，正数表示给定日期在当前日期之前，负数表示在当前日期之后
     */
    public static long pastHours(Long timestamp)
    {
        if (timestamp == null) return 0;
        return (System.currentTimeMillis() - timestamp) / MILLIS_PER_HOUR;
    }

    /**
     * 计算两个毫秒级时间戳之间相差天数.
     *
     * @param start 开始时间戳（毫秒）
     * @param end   结束开始时间戳（毫秒）
     * @return long 相隔天数
     */
    public static long getDaysBetween(long start, long end)
    {
        return (end - start) / MILLIS_PER_DAY;
    }

    /**
     * 计算两个日期之间相差天数(转为YYYY_MM_DD计算)
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    public static long getDaysBetween(String startDate, String endDate)
    {
        if (startDate == null || "".equals(startDate)) {
            return 0;
        }
        if (endDate == null || "".equals(endDate)) {
            return 0;
        }

        Date start, end;
        try {
            // 转换为标准时间
            start = parseDate(startDate, YYYY_MM_DD);
            end = parseDate(endDate, YYYY_MM_DD);
            return (end.getTime() - start.getTime()) / MILLIS_PER_DAY;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 计算两个日期之间相差天数(转为YYYY_MM_DD计算)
     *
     * @param start 计算开始日期
     * @param end   计算结束日期
     * @return long 相隔天数
     */
    public static long getDaysBetween(Date start, Date end)
    {
        if (start == null || end == null) {
            return 0;
        }
        // 将指定日期转换为yyyy-MM-dd格式
        start = parseDate(formatDate(start, YYYY_MM_DD));
        // 当前日期转换为yyyy-MM-dd格式
        end = parseDate(formatDate(end, YYYY_MM_DD));

        long diff = 0;
        if (start != null && end != null) {
            diff = (end.getTime() - start.getTime()) / MILLIS_PER_DAY;
        }
        return diff;
    }

    /**
     * 计算两个日期之前相隔多少周.
     *
     * @param start 计算开始时间
     * @param end   计算结束时间
     * @return long 相隔周数，向下取整
     */
    public static long getWeeksBetween(Date start, Date end)
    {
        return getDaysBetween(start, end) / DateUtils.DAYS_PER_WEEK;
    }

    /**
     * getMonthsBetween(查询两个日期相隔的月份)
     *
     * @param startDate 开始日期1 (格式yyyy-MM-dd)
     * @param endDate   截止日期2 (格式yyyy-MM-dd)
     * @return
     */
    public static int getMonthsBetween(String startDate, String endDate)
    {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(DateUtils.parseDate(startDate));
        c2.setTime(DateUtils.parseDate(endDate));
        int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        int month = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
        return Math.abs(year * 12 + month);
    }

    /**
     * 计算两个日期之前间隔的小时数.
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return String 相差的小时数，保留一位小数
     */
    public static long getHoursBetween(Date startDate, Date endDate)
    {
        if (startDate == null || endDate == null) return 0;
        long r = endDate.getTime() - startDate.getTime();
//        DecimalFormat df = new DecimalFormat("#.0");
//        double result = r * 1.0 / DateUtils.MILLIS_PER_HOUR;
//        return df.format(result);
        return r / MILLIS_PER_HOUR;
    }

    /**
     * 计算两个秒级时间戳间隔的小时数.
     *
     * @param start 开始时间
     * @param end   结束时间
     * @return String 相差的小时数
     */
    public static long getHoursBetween(Long start, Long end)
    {
        if (start == null || end == null) return 0;
        return (end - start) / MILLIS_PER_HOUR;
    }

    /**
     * getDayOfWeek(获取日期所在年份是星期几)
     *
     * @param dateStr 日期
     * @return 星期几
     */
    public static String getDayOfWeek(String dateStr)
    {
        String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Date date = parseDate(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int num = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return weekOfDays[num];
    }

    /**
     * getWeekOfYear(获取日期所在年份的周数)
     * 设置一周的第一天为星期一
     *
     * @param dateStr 日期
     * @return 星期几
     */
    public static int getWeekOfYear(String dateStr)
    {
        Date date = parseDate(dateStr);
        return getWeekOfYear(date);
    }

    /**
     * getWeekOfYear(获取日期所在年份的周数)
     * 一周的第一天为星期一
     *
     * @param date 日期
     * @return 星期几
     */
    public static int getWeekOfYear(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        // 设置一周的第一天为星期一
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);

        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取某年某月按天切片日期集合（某个月间隔多少天的日期集合）
     *
     * @param beginYear
     * @param beginMonth
     * @param k
     * @return
     */
    public static List<Date> getTimeList(int beginYear, int beginMonth, int k)
    {
        List<Date> list = new ArrayList<>();
        Calendar beginCal = new GregorianCalendar(beginYear, beginMonth, 1);
        int max = beginCal.getActualMaximum(Calendar.DATE);
        for (int i = 1; i < max; i = i + k) {
            list.add(beginCal.getTime());
            beginCal.add(Calendar.DATE, k);
        }
        beginCal = new GregorianCalendar(beginYear, beginMonth, max);
        list.add(beginCal.getTime());
        return list;
    }
}
